﻿#include "AutoTextCommand.h"

#include "../../../Memory/GameData.h"

inline constexpr std::u8string string_replace(std::u8string s, const std::u8string_view findS, const std::u8string_view replaceS) {
	for (size_t i{};;) {
		i = s.find(findS, i);
		if (i != std::string::npos)
			s.replace(i, findS.length(), replaceS);
		else
			return s;
	}
}

inline constexpr std::u8string parse(std::u8string s) {

	constexpr std::array<std::pair<std::u8string_view, std::u8string_view>, 7> patterns{ // string_view 中间含有 (char8_t)0 字符串初始化时会截断，必须标明长度
																						std::pair{u8"\\\\", std::u8string_view{u8"\\\0", 2}},
																						std::pair{u8"\\n", u8"\n"},
																						std::pair{u8"\\r", u8"\r"},
																						std::pair{u8"\\t", u8"\t"},
																						std::pair{u8"\\f", u8"\f"},
																						std::pair{u8"\\\"", u8"\""},
																						std::pair{std::u8string_view{u8"\\\0", 2}, u8"\\"}};
	for (const auto& p : patterns)
		s = string_replace(s, p.first, p.second);
	return s;
}

bool AutoTextCommand_onExecute(const fast_io::vector<std::u8string>& args) {
	auto& mode = args[1];
	if (args.size() == 2) {
		if (mode == u8"list") {
			if (SettingManager::autotextbindings.empty()) {
				C_GuiData::displayClientMessageC(Utils::TextColor::LIGHT_PURPLE, u8"[Helium] ", Utils::TextColor::RED, u8"You haven't set the macro yet");
			} else {
				C_GuiData::displayClientMessageC(Utils::TextColor::GRAY, u8"========================");
				for (auto& b : SettingManager::autotextbindings) {
					C_GuiData::displayClientMessageC(Utils::TextColor::YELLOW, fast_io::mnp::chvw(b.first), Utils::TextColor::BLUE, u8"-->", Utils::TextColor::GOLD, b.second);
				}
				C_GuiData::displayClientMessageC(Utils::TextColor::GRAY, u8"========================");
			}
			return true;
		} else {
			return false;
		}
	} else if (args.size() < 3)
		return false;

	auto& key = args[2];

	if (mode == u8"set") {

		if (key.size() != 1)
			return false;

		std::u8string text{};
		for (size_t i = 3; i < args.size(); i++) {
			if (i > 3) [[likely]]
				text.push_back(u8' ');
			text.append(args[i]);
		}
		
		SettingManager::autotextbindings[fast_io::char_category::to_c_upper(key.front())] = parse(text);
		C_GuiData::displayClientMessageC(Utils::TextColor::LIGHT_PURPLE, u8"[Helium] ", Utils::TextColor::GREEN, u8"Successfully set!");
		return true;
	} else if (mode == u8"reset") {
		if (key == u8"all") 
			SettingManager::autotextbindings.clear();
		else {
			if (key.size() != 1)
				return false;
			SettingManager::autotextbindings.erase(fast_io::char_category::to_c_upper(key.front()));
		}
		C_GuiData::displayClientMessageC(Utils::TextColor::LIGHT_PURPLE, u8"[Helium] ", Utils::TextColor::GREEN, u8"Successfully reset!");
		return true;
	} else {
		return false;
	}
}

fast_io::vector<aliasList_struct> keys{};

bool listKeys(fast_io::vector<std::u8string>*) {
	keys.clear();
	keys.reserve(SettingManager::autotextbindings.size());
	keys.emplace_back_unchecked(stringview_Object{u8"all", nullptr});
	for (auto& k : SettingManager::autotextbindings)
		keys.emplace_back_unchecked(string_Object{fast_io::u8concat(fast_io::mnp::chvw(k.first)), nullptr});

	return true;
}

ICommand AutoTextCommand{
	u8"autotext",
	u8".autotext [set <key> <text>, reset <key>|all, list]",
	{u8"Set small macros to send message quickly", u8"设置小型宏以快速发送消息", u8"設定小型宏以快速發送消息", u8"メッセージを迅速に送信するためのミニマクロの設定"},
	{},
	fast_io::vector<aliasList_struct>{
		aliasList_struct{stringview_Object{u8"set", nullptr}},
		aliasList_struct{stringview_Judge{u8"reset", &keys, &listKeys}},
		aliasList_struct{stringview_Object{u8"list", nullptr}}},  // If empty must use fast_io::vector<aliasList_struct>{}
	nullptr,
	&AutoTextCommand_onExecute};